﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Xml.Serialization;
using ElectronicCommerce.Framework.ServiceModel.WCF.BindingMessage;

namespace ElectronicCommerce.Framework.ServiceModel.WCF.TransferElement
{
    public class BasicHttpBindingHandler : IGetBindingByConfig
    {
        #region IGetBindingByConfig Members

        public System.ServiceModel.Channels.Binding GetBindingMsgByConfig(string configStr)
        {
            if (string.IsNullOrEmpty(configStr))
                return new BasicHttpBinding();
            else
            {
                XmlSerializer serial = new XmlSerializer(typeof(BasicHttpBindingMsg));
                BasicHttpBindingMsg bindingMsg = (BasicHttpBindingMsg)serial.Deserialize(new StringReader(configStr));
                return GetBindingFromMsg(bindingMsg);
            }
        }

        #endregion

        private BasicHttpBinding GetBindingFromMsg(BasicHttpBindingMsg bindingMsg)
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.AllowCookies = bindingMsg.allowCookies;
            binding.BypassProxyOnLocal = bindingMsg.bypassProxyOnLocal;
            if (!string.IsNullOrEmpty(bindingMsg.closeTimeout))
                binding.CloseTimeout = TimeSpan.Parse(bindingMsg.closeTimeout);

            binding.HostNameComparisonMode = (HostNameComparisonMode)bindingMsg.hostNameComparisonMode;

            binding.MaxBufferPoolSize = bindingMsg.maxBufferPoolSize;
            binding.MaxBufferSize = bindingMsg.maxBufferSize;
            binding.MaxReceivedMessageSize = bindingMsg.maxReceivedMessageSize;

            binding.MessageEncoding = (WSMessageEncoding)bindingMsg.messageEncoding;

            if (!string.IsNullOrEmpty(bindingMsg.name))
                binding.Name = bindingMsg.name;

            if (!string.IsNullOrEmpty(bindingMsg.openTimeout))
                binding.OpenTimeout = TimeSpan.Parse(bindingMsg.openTimeout);

            if (!string.IsNullOrEmpty(bindingMsg.proxyAddress))
                binding.ProxyAddress = new Uri(bindingMsg.proxyAddress);

            if (bindingMsg.readerQuotas != null)
            {
                binding.ReaderQuotas.MaxArrayLength = bindingMsg.readerQuotas.maxArrayLength;
                binding.ReaderQuotas.MaxBytesPerRead = bindingMsg.readerQuotas.maxBytesPerRead;
                binding.ReaderQuotas.MaxDepth = bindingMsg.readerQuotas.maxDepth;
                binding.ReaderQuotas.MaxNameTableCharCount = bindingMsg.readerQuotas.maxNameTableCharCount;
                binding.ReaderQuotas.MaxStringContentLength = bindingMsg.readerQuotas.maxStringContentLength;
            }

            if (!string.IsNullOrEmpty(bindingMsg.receiveTimeout))
                binding.ReceiveTimeout = TimeSpan.Parse(bindingMsg.receiveTimeout);

            if (!string.IsNullOrEmpty(bindingMsg.sendTimeout))
                binding.SendTimeout = TimeSpan.Parse(bindingMsg.sendTimeout);

            if (!string.IsNullOrEmpty(bindingMsg.textEncoding))
                binding.TextEncoding = Encoding.GetEncoding(bindingMsg.textEncoding);
            binding.TransferMode = (TransferMode)bindingMsg.transferMode;
            binding.UseDefaultWebProxy = bindingMsg.useDefaultWebProxy;

            if (bindingMsg.security != null)
            {
                TranBasicHttpSecurity(bindingMsg, binding);
            }

            return binding;
        }

        private void TranBasicHttpSecurity(BasicHttpBindingMsg bindingMsg, BasicHttpBinding binding)
        {
            switch (bindingMsg.security.mode)
            {
                case BasicHttpBindingSecurityMode.None:
                    binding.Security.Mode = BasicHttpSecurityMode.None;
                    break;
                case BasicHttpBindingSecurityMode.Message:
                    binding.Security.Mode = BasicHttpSecurityMode.Message;
                    if (bindingMsg.security.message.algorithmSuite != null)
                    {
                        binding.Security.Message.AlgorithmSuite = (System.ServiceModel.Security.SecurityAlgorithmSuite)Convert.ChangeType(bindingMsg.security.message.algorithmSuite, typeof(System.ServiceModel.Security.SecurityAlgorithmSuite));
                    }
                    binding.Security.Message.ClientCredentialType = (BasicHttpMessageCredentialType)bindingMsg.security.message.clientCredentialType;
                    break;
                case BasicHttpBindingSecurityMode.Transport:
                    binding.Security.Mode = BasicHttpSecurityMode.Transport;
                    binding.Security.Transport.ClientCredentialType = (HttpClientCredentialType)bindingMsg.security.transport.clientCredentialType;
                    binding.Security.Transport.ProxyCredentialType = (HttpProxyCredentialType)bindingMsg.security.transport.proxyCredentialType;
                    if (bindingMsg.security.transport.realm != null)
                    {
                        binding.Security.Transport.Realm = bindingMsg.security.transport.realm;
                    }
                    break;
                case BasicHttpBindingSecurityMode.TransportWithMessageCredential:
                    binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
                    if (bindingMsg.security.message.algorithmSuite != null)
                    {
                        binding.Security.Message.AlgorithmSuite = (System.ServiceModel.Security.SecurityAlgorithmSuite)Convert.ChangeType(bindingMsg.security.message.algorithmSuite, typeof(System.ServiceModel.Security.SecurityAlgorithmSuite));
                    }
                    binding.Security.Message.ClientCredentialType = (BasicHttpMessageCredentialType)bindingMsg.security.message.clientCredentialType;
                    binding.Security.Transport.ClientCredentialType = (HttpClientCredentialType)bindingMsg.security.transport.clientCredentialType;
                    binding.Security.Transport.ProxyCredentialType = (HttpProxyCredentialType)bindingMsg.security.transport.proxyCredentialType;
                    if (bindingMsg.security.transport.realm != null)
                    {
                        binding.Security.Transport.Realm = bindingMsg.security.transport.realm;
                    }
                    break;
                default:
                    binding.Security.Mode = BasicHttpSecurityMode.None;
                    break;
            }
        }



        #region IGetBindingByConfig Members


        public string GetAddress(string templateAddress)
        {
            return String.Format("http://{0}", templateAddress);
        }

        #endregion
    }
}
